//
//  WSBaseHttp.m
//  WSBaseKit
//
//  Created by zhangcong on 2020/8/12.
//  Copyright © 2020 zhangcong. All rights reserved.
//

#import "WSBaseHttp.h"

#import <AFNetworking.h>
#import <AFHTTPSessionManager.h>
#import <AFURLRequestSerialization.h>
//#import "DeviceNameLib.h"
#import <NSObject+YYModel.h>

#define STATUS_OK 1000

@implementation WSBaseHttp


- (AFHTTPSessionManager*) createOperationManager:(NSSet*) contentTypes timeoutInterval:(NSTimeInterval) timeoutInterval {
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    [manager.requestSerializer willChangeValueForKey:@"timeoutInterval"];
    manager.requestSerializer.timeoutInterval = timeoutInterval;
    [manager.requestSerializer didChangeValueForKey:@"timeoutInterval"];
    manager.responseSerializer.acceptableContentTypes = contentTypes;
    
    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    manager.requestSerializer = AFHTTPRequestSerializer.serializer;
    
    manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;
    
    [manager.requestSerializer setValue:@"iOS" forHTTPHeaderField:@"APP-SYSTEM"];
//    [manager.requestSerializer setValue:[DeviceNameLib deviceName] forHTTPHeaderField:@"PHONE-MODEL"];
    
#if 0
    if (UserDataHandler.getUserInfo.token > 0) {
//        [manager.requestSerializer setValue:[NSString stringWithFormat:@"Bearer %@",UserDataHandler.getUserInfo.token?:@""] forHTTPHeaderField:@"Authorization"];
//
        NSString *token = UserDataHandler.getUserInfo.token;
//        NSString *token = @"123";

        [manager.requestSerializer setValue:[NSString stringWithFormat:@"%@",token] forHTTPHeaderField:@"SANGUOSHA-TOKEN"];
        
    }
    
    NSString *getuiClintId = GetuiHelper.sharedInstance.getuiClientId;
    if (getuiClintId.length > 0) {
        [manager.requestSerializer setValue:getuiClintId forHTTPHeaderField:@"GETUI-CLIENT-ID"];
    }
    
    NSString *deviceId = [DobestDeviceInfo getDeviceId];
    if (deviceId.length > 0) {
        [manager.requestSerializer setValue:deviceId forHTTPHeaderField:@"DEVICE-ID"];
    }
#endif
    return manager;
}

- (void)POST:(NSString *)url params:(NSDictionary *)params success:(SuccessBlock)success error:(ErrorBlock)errorBlock{
    [self POST:url params:params needToken:YES success:success error:errorBlock];
}
- (void)POST:(NSString *)url params:(NSDictionary *)params needToken:(BOOL)needToken success:(SuccessBlock)success error:(ErrorBlock)errorBlock{
    
    if ([self params:params needToken:needToken error:errorBlock]) {
        [self postRequest:url parameters:params complete:^(id data) {
            if (success) {
                success(data[@"data"],data[@"msg"],[data[@"code"] integerValue]);
            }
        } error:errorBlock];
    }
}

- (void)GET:(NSString *)url params:(NSDictionary *)params success:(SuccessBlock)success error:(ErrorBlock)errorBlock {
    [self getRequest:url parameters:params complete:^(id data) {
        if (success) {
            success(data[@"data"],data[@"message"],[data[@"code"] integerValue]);
        }
    } error:errorBlock];
}

- (void)PUT:(NSString *)url params:(NSDictionary *)params success:(SuccessBlock)success error:(ErrorBlock)errorBlock {
    [self putRequest:url parameters:params complete:^(id data) {
        if (success) {
            success(data[@"data"],data[@"message"],[data[@"code"] integerValue]);
        }
    } error:errorBlock];
}

- (void)postRequest:(NSString *)path parameters:(NSDictionary *)parameters complete:(CompleteBlock)complete error:(ErrorBlock)errorBlock {
    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:parameters];
    
    NSLog(@"\n POST url \t %@\nparameters\n%@",path,params);
    
    AFHTTPSessionManager *manager = [self createOperationManager:[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",@"text/plain", nil] timeoutInterval:30.f];
    
    __weak WSBaseHttp *SELF = self;
    [manager POST:path parameters:nil headers:self.headerDict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [SELF success:task responseObject:responseObject complete:complete error:errorBlock];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (errorBlock != nil) {
            errorBlock(error);
        }
    }];
}

- (void)getRequest:(NSString *)path parameters:(NSDictionary *)parameters complete:(CompleteBlock)complete error:(ErrorBlock)errorBlock {
    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:parameters];
    
    
    NSLog(@"\n GET url \t %@\nparameters\n%@",path,params);
    
    AFHTTPSessionManager *manager = [self createOperationManager:[NSSet setWithObjects:@"text/html",@"text/plain", @"application/json", @"text/json" , @"text/javascript", nil] timeoutInterval:30.f];
    //    [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",@"text/plain", nil]
//    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

    
    __weak WSBaseHttp *SELF = self;
    
    [manager GET:path parameters:params headers:self.headerDict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [SELF success:task responseObject:responseObject complete:complete error:errorBlock];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (errorBlock != nil) {
            errorBlock(error);
        }
    }];
}

- (void)putRequest:(NSString *)path parameters:(NSDictionary *)parameters complete:(CompleteBlock)complete error:(ErrorBlock)errorBlock {
    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:parameters];
    
    
    NSLog(@"\n PUT url \t %@\nparameters\n%@",path,params);
    
    AFHTTPSessionManager *manager = [self createOperationManager:[NSSet setWithObjects:@"text/html",@"text/plain", @"application/json", @"text/json" , @"text/javascript", nil] timeoutInterval:30.f];
    
    __weak WSBaseHttp *SELF = self;
    
    [manager PUT:path parameters:params headers:self.headerDict success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [SELF success:task responseObject:responseObject complete:complete error:errorBlock];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (errorBlock != nil) {
            errorBlock(error);
        }
    }];
}

- (void)deleteRequest:(NSString *)path parameters:(NSDictionary *)parameters complete:(CompleteBlock)complete error:(ErrorBlock)errorBlock {
    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:parameters];
    
    
    NSLog(@"\n PUT url \t %@\nparameters\n%@",path,params);
    
    AFHTTPSessionManager *manager = [self createOperationManager:[NSSet setWithObjects:@"text/html",@"text/plain", @"application/json", @"text/json" , @"text/javascript", nil] timeoutInterval:30.f];
    
    __weak WSBaseHttp *SELF = self;
    
    [manager DELETE:path parameters:params headers:self.headerDict success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [SELF success:task responseObject:responseObject complete:complete error:errorBlock];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (errorBlock != nil) {
            errorBlock(error);
        }
    }];
}

- (void)success:(NSURLSessionDataTask *)task responseObject:(id)responseObject complete:(CompleteBlock)complete error:(ErrorBlock)errorBlock {
    NSString *strJson = [self convertToJSONData:responseObject];
    NSData *strData = [strJson dataUsingEncoding:NSUTF8StringEncoding];
    NSError __autoreleasing *error = nil;
    id data = [NSJSONSerialization JSONObjectWithData:strData options:NSJSONReadingMutableLeaves error:&error];
    [self.class logResponseObject:data];
    if ( error == nil && data != nil ) {
        
        NSInteger status = [[data valueForKey:@"code"] integerValue];
        
        if ([data valueForKey:@"code"]) {
            status = [[data valueForKey:@"code"] integerValue];
        }
        else if ([data valueForKey:@"cd"]) {
            status = [[data valueForKey:@"cd"] integerValue];
        }

        if (status == STATUS_OK) {
//            NSInteger okStatus = [[[data valueForKey:@"data"] objectForKey:@"code"] integerValue];
//            if (okStatus == 0) {
                if (complete != nil)
                    complete(data[@"data"]);
//            }
//            else if( errorBlock ){
//                NSString *failed = [data[@"data"] objectForKey:@"msg"];
//                if ( ! failed ) {
//                    failed = [((NSDictionary *)data) objectForKey:@"msg"];
//                }
//                if ( ! failed ) {
//                    failed = @"failed";
//                }
//
//                NSInteger errorCode = [[data[@"data"] objectForKey:@"code"] integerValue];
//                NSDictionary *userInfo = [NSDictionary dictionaryWithObject:failed forKey:NSLocalizedDescriptionKey];
//                errorBlock([NSError errorWithDomain:kAppNSErrorDomain code:errorCode userInfo:userInfo]);
//            }
        }
        else if( errorBlock ){
            NSString *failed = [((NSDictionary *)data) objectForKey:@"msg"];
            if ( ! failed ) {
                failed = [((NSDictionary *)data) objectForKey:@"msg"];
            }
            if ( ! failed ) {
                failed = @"failed";
            }
            NSDictionary *userInfo = [NSDictionary dictionaryWithObject:failed forKey:NSLocalizedDescriptionKey];
            errorBlock([NSError errorWithDomain:kAppNSErrorDomain code:status userInfo:userInfo]);
        }
    }
    else if( errorBlock ){
        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:@"json格式错误" forKey:NSLocalizedDescriptionKey];
        errorBlock([NSError errorWithDomain:kAppNSErrorDomain code:kAppNSErrorServer userInfo:userInfo]);
    }
}


#pragma mark - 直接返回model

- (void)postModelRequest:(NSString *)path parameters:(NSDictionary *)parameters modelClass:(Class)modelClass complete:(CompleteBlock)complete error:(ErrorBlock)error {
    __weak WSBaseHttp *SELF = self;
    [self postRequest:path parameters:parameters complete:^(id data) {
        [SELF parseModel:data[@"data"] modelClass:modelClass complete:complete error:error];
    }           error:error];
}

- (void)postModelArrayRequest:(NSString *)path parameters:(NSDictionary *)parameters modelClass:(Class)modelClass complete:(CompleteBlock)complete error:(ErrorBlock)error {
    
    __weak WSBaseHttp *SELF = self;
    [self postRequest:path parameters:parameters complete:^(id data) {
        
        [SELF parseModelArray:data[@"data"] modelClass:modelClass complete:complete error:error];
    }           error:error];
}


#pragma mark - 数据解析
- (void)parseModel:(id)data modelClass:(Class)modelClass complete:(CompleteBlock)complete error:(ErrorBlock)errorBlock {
    if (complete) {
        if (modelClass == nil) {
            complete(data);
        }
        else if (data == nil || [data isKindOfClass:NSNull.class]) {
            complete(nil);
        }
        else if ([data isKindOfClass:NSArray.class] && [(NSArray *)data count] == 0) {
            complete(nil);
        }
        else {
            
            NSError __autoreleasing *error = nil;
            
            id model = [modelClass modelWithJSON:data];
            
            
            if (error == nil && model != nil)
                complete(model);
            else {
                if (error) {
                    NSLog(@"%@", error);
                }
                NSDictionary *userInfo = [NSDictionary dictionaryWithObject:@"解析数据失败" forKey:NSLocalizedDescriptionKey];
                errorBlock([NSError errorWithDomain:kAppNSErrorDomain code:kAppNSErrorJsonCode userInfo:userInfo]);
            }
        }
    }
}

- (void)parseModelArray:(id)data modelClass:(Class)modelClass complete:(CompleteBlock)complete error:(ErrorBlock)errorBlock {
    if (complete) {
        if (modelClass == nil) {
            complete(data);
        }
        else if (data == nil || [data isKindOfClass:NSNull.class]) {
            complete(nil);
        }
        else {
            NSError __autoreleasing *error = nil;
            NSArray *models = [NSArray modelArrayWithClass:modelClass json:data];
            
            if (error == nil && models != nil)
                complete(models);
            else {
                NSDictionary *userInfo = [NSDictionary dictionaryWithObject:@"解析数据失败" forKey:NSLocalizedDescriptionKey];
                errorBlock([NSError errorWithDomain:kAppNSErrorDomain code:kAppNSErrorJsonCode userInfo:userInfo]);
            }
        }
    }
}



- (NSString*)convertToJSONData:(id)infoDict{
    NSError *error;
    
    NSData *jsonData;
    if ([infoDict isKindOfClass:NSData.class]) {
        jsonData = infoDict;
    }
    else {
        jsonData = [NSJSONSerialization dataWithJSONObject:infoDict
                                                   options:NSJSONWritingPrettyPrinted                                                         error:&error];
    }
    
    
    NSString *jsonString = @"";
    if (! jsonData)
    {
        NSLog(@"Got an error: %@", error);
    }else
    {
        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        
    }
    
    jsonString = [jsonString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];  //去除掉首尾的空白字符和换行字符
    
    [jsonString stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    
    return jsonString;
}

/**
 自动追加token
 
 @param params 要追加的参数
 @param needToken 是否需要追加token
 @return 是否需要请求接口
 */
- (BOOL)params:(NSDictionary *)params needToken:(BOOL)needToken error:(ErrorBlock)error{
    if (needToken) {
        if (params) {
            //            if ([UserDataHandler getUserInfo].userID.length > 0){
            //                return YES;
            //            } else{
            //                [self didError:kAppNSErrorTokenCode strError:@"您还未登录" error:error];
            //            }
        } else{
            //            [App_Window.rootViewController showTips:@"参数不能为空!" afterDelay:1.5];
        }
        
        return NO;
    }
    
    return YES;
}

- (void)didError:(NSInteger)errorCode strError:(NSString *)strError error:(ErrorBlock)error {
    if (error != nil) {
        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:strError forKey:NSLocalizedDescriptionKey];
        error([NSError errorWithDomain:kAppNSErrorDomain code:errorCode userInfo:userInfo]);
    }
}

+ (void)logResponseObject:(id)responseObject{
    
#ifdef DEBUG
    if (responseObject && ![responseObject isKindOfClass:[NSNull class]]) {
        NSData *data;
        if ([responseObject isKindOfClass:[NSData class]]) {
            data = responseObject;
        } else{
            data = [NSJSONSerialization dataWithJSONObject:responseObject options:NSJSONWritingPrettyPrinted error:nil];
        }
        NSLog(@"\n\nresponseObject\n%@\n\n\n\n",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
    } else{
        NSLog(@"\n\nresponseObject\n%@\n\n\n\n",responseObject);
    }
#endif
    
}

- (BOOL)addCurrentUserToken:(NSDictionary *)parameter isMustToken:(BOOL)isMustToken error:(ErrorBlock)error {
    return NO;
}

#pragma mark -- 项目子类重写
- (NSInteger)success_code {
    return STATUS_OK;
}


@end
